#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <string.h>
#include "parse.h"
#include "buffer.h"
#include "response.h"
#include "split.h"

#define LISO_PORT 9999
#define BUF_SIZE 4096 


//服务器监听套接字
int sock = -1;
char buf[BUF_SIZE]; //暂存接收数据的缓冲区

int close_socket(int socket); 

int main(int argc, char *argv[]) {
    socklen_t cli_size;
    struct sockaddr_in addr, cli_addr;

    printf("----- Liso Server -----\n");

    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        printf("Failed creating socket.\n");
        return EXIT_FAILURE;
    }

    addr.sin_family = AF_INET; // ipv4
    addr.sin_port = htons(LISO_PORT);
    addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr))) {
        close_socket(sock);
        printf("Failed binding socket.\n");
        return EXIT_FAILURE;
    }

    if (listen(sock, 5)) {
        close_socket(sock);
        printf("Error listening on socket.\n");
        return EXIT_FAILURE;
    }


    while (1) {
        //监听新连接
        cli_size = sizeof(cli_addr);
        printf("Waiting for connection...\n");
        int cli_sock = accept(sock, (struct sockaddr *) &cli_addr, &cli_size); //建立连接
        if(cli_sock == -1){
            printf("Error accepting connection.\n");
            close_socket(sock);
            return EXIT_FAILURE;
        }
        printf("New connection from %s:%d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port));

        Buffer bf_recv; //请求接收缓冲区
        buffer_init(&bf_recv);
        bool isPersistent;
        int readret = 0;
        while((readret = recv(cli_sock,buf,BUF_SIZE,0)) >= 1){ 
            buf[readret] = '\0'; //显式加上结束符，保证安全
            buffer_append(&bf_recv,buf,readret);//接收客户端数据到缓冲区
            printf("Received (total %d bytes) messages:\n",readret); 
            printf("---------------------------------------------\n");
            printf("%s ",bf_recv.data); 
            printf("---------------------------------------------\n");

            int reqCnt = 0;
            Buffer** reqs = split(bf_recv.data,&reqCnt); //分割请求
            for(int i=0;i < reqCnt;i++){
                if (reqs[i]->len == 0) { // 跳过空请求
                    buffer_free(reqs[i]);
                    free(reqs[i]);
                    continue;
                }
                isPersistent = parseRequest(reqs[i], &cli_addr, cli_sock);
                if(!isPersistent) {
                    printf("yesyes\n");
                    break;
                }
            }

            for (int i = 0;i < reqCnt; i++) {
                buffer_free(reqs[i]);
                free(reqs[i]);
            }
            free(reqs);

            if(!isPersistent) break;

            memset(buf, 0, BUF_SIZE);
            buffer_clear(&bf_recv);
        }

        buffer_free(&bf_recv);

        if (close_socket(cli_sock)){
            close_socket(sock);
            printf("Error closing client socket.\n");
            return EXIT_FAILURE;
        }
        printf("Closed connection from %s:%d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port));
    }
    close_socket(sock);
    return EXIT_SUCCESS;
}


int close_socket(int socket) {
    if (close(socket)) {
        fprintf(stderr, "Failed closing socket.\n");
        return 1;
    }
    return 0;
}


// int deal_buf(dynamic_buffer * dbuf, size_t readret, int client_sock, int sock, int fd_in, struct sockaddr_in cli_addr){
// 	char * t, *temp=dbuf->buf;
// 	int cnt = 0;
// 	/* deal pipeline */
// 	dynamic_buffer *return_buffer = (dynamic_buffer*) malloc(sizeof(dynamic_buffer));
// 	init_dynamic_buffer(return_buffer);
// 	while((t=strstr(temp,dest))!=NULL){
// 		int len = t - temp;

// 		dynamic_buffer * each = (dynamic_buffer *)malloc(sizeof(dynamic_buffer));
// 		init_dynamic_buffer(each);
// 		memset_dynamic_buffer(each);
// 		append_dynamic_buffer(each, temp, len);
// 		append_dynamic_buffer(each, dest, strlen(dest));
// 		temp = t + strlen(dest);

// 		Return_value result = handle_request(client_sock, sock, each, cli_addr);	
// 		append_dynamic_buffer(return_buffer, each->buf, each->current);

// 		if(result==CLOSE)
// 			return CLOSE;
// 		free_dynamic_buffer(each);
// 	}
// 	update_dynamic_buffer(dbuf, temp);
// 	if(!return_buffer->current){
// 		free_dynamic_buffer(return_buffer);
// 		return PERSISTENT;
// 	}
// 	if (send(client_sock, return_buffer->buf, return_buffer->current, 0) != return_buffer->current)
// 	{
// 		close_socket(client_sock);
// 		close_socket(sock);
// 		free_dynamic_buffer(return_buffer);
// 		fprintf(stderr, "Error sending to client.\n");
// 		return EXIT_FAILURE;
// 	}

// 	free_dynamic_buffer(return_buffer);
// 	return PERSISTENT;
// } 